Dart擁有int、double、String、bool等常見的變數型態
在定義變數的時候你可以選擇給他明確的型態或是用「var」讓Dart來幫你決定
void main() {
var a = 1; //int 整數
var b = "1"; // String 字串
var c = 1.1; // double 浮點數
if (a is int) {
print('a is int'); // Output: a is int
}
if (b is String) {
print('b is String'); // Output: b is String
}
if (c is double) {
print('c is double'); // Output: c is double
}
}
需要注意的是假如你用的是var在宣告賦值後就不能再賦予它其他型態的值了。
void main() {
var a = 1;
a = "123"; // Error: A value of type 'String' can't be assigned to a variable of type 'int'.
}
你也可以使用dynamic來做宣告,dynamic是所有物件的基礎類型,也就是說它可以代表任何物件。
換句話來說,Dart的「dynamic」和JavaScript的「var」非常相似,可以隨時替換不同型態的值給變數。
void main() {
dynamic a = 1;
a = '123'; // no error
}
再舉一個例子,看看你能否舉一反三。
void main() {
var a;
a = 1;
print(a); // Output:1
a = "123";
print(a); // Output: 123
}
雖然這次也是使用var來宣告,但卻可以替換成不同型態的值,這是由於一開始並未給變數a初始值,因此var會給予變數a dynamic型態,所以就算替換了不同型態的值也不會報錯。
Dart還有List可以使用,定義list需要使用方括號[]
,同樣的你可以在宣告的時候定義儲存值的型態,或是用dynamic來接受所有的型態。
如果list內的值不想要被更動,在宣告時可以使用const關鍵字來把值固定,之後就無法對List做新增修改刪除了。
void main() {
List<dynamic> a = const [1, '123', true];
print(a[1]); // Output:123
a.add(123); // error
}
最後要介紹的是Map,Map是使用key-value的方式來儲存的資料型態,Map是使用大括號{}
,以Key:Value
的方式定義。
之後在實作專案裡面會使用到Map來儲存從Youtube Api回傳過來的JSON Data,大家可以先去看一下JSON是怎麼樣的資料格式喔~
void main() {
var map = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
};
print(map['key1']); // Output: value1
print(map['test']); // Output: null
map['key4'] = 'value4';
//Length
print(map.length); //Output: 4
print(map.containsKey('value1')); // Output: false
print(map.entries); // Output: (MapEntry(key1: value1), MapEntry(key2: value2), MapEntry(key3: value3), MapEntry(key4: value4))
print(map.values); // Output: (value1, value2, value3, value4)
}
function是很重要的東西,它能夠讓你的code能夠重複使用(code reuse),方便你移植維護專案。
在Dart裡,function被視為物件,可以把function存成變數或是作為其他function的參數來使用。
接下來就來瞭解如何定義function吧。
先來個基礎的範例
void main() {
print(birthday('John', 11, 22));
// Output: John's birthday is 11/22.
}
String birthday(String name, int month, int day) {
// 若想在字串內插入變數可以使用${var}或是$var喔
return "${name}'s birthday is $month/$day.";
}
這裡我們定義一個function取名為「birthday」,它需要3個參數分別是名字、月份、日期,最後回傳字串。
birthday前的String
表示了這個function回傳的型態(String name, int month, int day)
定義它需要的參數return "${name}'s birthday is $month/$day."
則是回傳的結果
這時回頭看一下程式的入口main() 這個function,可以發現它並沒有要求參數;而它前方的void則表示它不會有回傳值。
這個例子還能被改寫成下面兩種,結果會是一樣的。
// Dart裡可以省略回傳的型態,Dart會根據回傳值自動判定
// (但並不建議這樣寫,會不易維護程式碼)
birthday(String name, int month, int day) {
return "${name}'s birthday is $month/$day.";
}
// 假如你的function只有一行,就可以使用「=>」來簡化
// => expr是{return expr;}的縮寫
String birthday(String name, int month, int day) =>
"${name}'s birthday is $month/$day.";
function也可以使用命名參數(Named parameters),來看個例子。
void main() {
print(birthday(name:'John', day:22, ));
// Output: John's birthday is null/22.
}
birthday({String name='Amy', int month, int day}) =>
"${name}'s birthday is $month/$day.";
注意定義birthday
在參數的地方是使用{}
包著。
命名參數能想像成前面提到的Map資料結構,由Key對應到Value
name、month、day是Key
John、11、22則是對應的Value
使用時給予參數的順序並不影響結果,只要key和value對應正確即可。
命名參數可以為空,也可以提供預設值,若沒提供則為null(如上例沒有提供month
,month
輸出就為null)
今天最後來介紹匿名函式(Anonymous Function),顧名思義就是沒有名字的function,通常用於一行就能解決或是只使用一次的function。
void main() {
var nums = [1, 2, 3, 4, 5];
iterNums(nums);
}
void iterNums(List nums) {
nums.forEach((num)=>print("Number is $num"));
}
forEach
是list的method,會迭代list內的每個元素並把它作為參數傳進匿名函式中。(num)=>print("Number is $num")
就是匿名函式,可以發現它並沒有名字只由()
所組成,而裡面的num
則是會被帶進這個函式裡使用的參數。
匿名函式非常方便所以在Flutter很常見,例如設定Button的點擊行為或是迭代list時都能看到。
今天介紹了Dart的基本型態以及function的使用方式,有沒有發現Dart非常平易近人又有許多方便的功能呢
明天我會介紹Dart的流程控制以及例外處理,明天見!